home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Franz PD
/
Franz PD Disk #324 (1994-04)(Rhein-Sieg-Soft).zip
/
Franz PD Disk #324 (1994-04)(Rhein-Sieg-Soft).adf
/
VideoText3.5
/
source
/
pagelist.p
< prev
next >
Wrap
Text File
|
1994-04-01
|
6KB
|
168 lines
UNIT pagelist; {$project vt}
{ Verwaltung der verketteten Seitenliste zum Programm VideoText }
INTERFACE; FROM vt USES global;
PROCEDURE kill_list;
PROCEDURE del_from_list(VAR target: p_onepage);
FUNCTION hunt_in_list(pg,sp: Integer; exact: Boolean): p_onepage;
PROCEDURE ins_to_list(item: p_onepage);
PROCEDURE add_to_list(item: p_onepage);
FUNCTION next_magazine(item: p_onepage): p_onepage;
FUNCTION prev_magazine(item: p_onepage): p_onepage;
{ ---------------------------------------------------------------------- }
IMPLEMENTATION;
{$opt b-}
PROCEDURE kill_list;
{ Alle Seiten wegwerfen. }
VAR hilf: p_onepage;
BEGIN
hilf := root;
WHILE root<>Nil DO BEGIN
root := root^.next;
Dispose(hilf);
hilf := root;
END;
END;
PROCEDURE del_from_list{(VAR target: p_onepage)};
{ Die bezeichnete Seite aus der Liste wegwerfen. Der übergebene Zeiger wird }
{ anschließend wieder auf einen sinnvollen Inhalt gesetzt: }
{ - auf den Nachfolger der gelöschten Seite, falls sie einen hat, sonst }
{ - auf ihren Vorgänger (d. h. Listenende oder Nil) }
VAR hilf: p_onepage;
BEGIN
IF target^.prev<>Nil THEN
target^.prev^.next := target^.next ELSE root := target^.next;
IF target^.next<>Nil THEN
target^.next^.prev := target^.prev;
hilf := target;
target := hilf^.next;
IF target = Nil THEN target := hilf^.prev;
Dispose(hilf);
END;
FUNCTION hunt_in_list{(pg,sp: Integer; exact: Boolean): p_onepage};
{ Liefert einen Zeiger auf die durch <pg>, <sp> beschriebene Seite in der }
{ Liste. Falls eine entsprechende Seite nicht gefunden wird, ist das }
{ Resultat für exact=false der nächsthöhere existierende Eintrag (bzw. das }
{ Listenende, wenn es keinen höheren Eintrag gibt), für exact=true einfach }
{ Nil. Letztere Variante funktioniert dafür auch auf unsortierten Listen, }
{ d. h. solchen, die mit add_to_list() statt ins_to_list() aufgebaut wurden. }
VAR hilf: p_onepage;
BEGIN
hilf := root;
IF hilf<>Nil THEN
IF exact THEN BEGIN
{ richtige Seitennummer finden }
WHILE ((hilf^.pg<>pg) OR (hilf^.sp<>sp)) AND (hilf^.next<>Nil) DO
hilf := hilf^.next;
IF ((hilf^.pg<>pg) OR (hilf^.sp<>sp)) THEN
hilf := Nil; {=hilf^.next}
END ELSE BEGIN
{ richtige oder nächsthöhere Seitennummer finden }
WHILE (hilf^.pg<pg) AND (hilf^.next<>Nil) DO
hilf := hilf^.next;
{ Wenn die Seitennummer stimmt, noch die Unterseite finden }
WHILE (hilf^.pg=pg) AND (hilf^.sp<sp) AND (hilf^.next<>Nil) DO
hilf := hilf^.next;
END;
hunt_in_list := hilf;
END;
PROCEDURE ins_to_list{(item: p_onepage)};
{ Neue Seite nach Seiten- und Unterseitennummer in die Liste einsortieren. }
{ Es wird *nicht* überprüft, ob bereits ein gleichartiger Eintrag existiert. }
{ Denn das Überschreiben eines veralteten Seiteninhalts sollte sich auch auf }
{ andere Weise ausführen lassen, als daß New() und Dispose() direkt }
{ nacheinander aufgerufen werden müssen - Äh! }
VAR hilf: p_onepage;
BEGIN
IF root=Nil THEN BEGIN
root := item
item^.next := Nil;
item^.prev := Nil;
END ELSE BEGIN
hilf := hunt_in_list(item^.pg,item^.sp,false);
{ hilf zeigt jetzt auf die Seite, vor der eingefügt werden sollte, bzw. }
{ auf das Listenende, falls die neue Seite die höchste aller Nummern hat. }
IF (hilf^.pg>item^.pg) OR ((hilf^.pg=item^.pg) AND (hilf^.sp>item^.sp))
THEN BEGIN { Normalfall, vor hilf einfügen }
item^.prev := hilf^.prev;
item^.next := hilf;
IF hilf^.prev<>Nil THEN hilf^.prev^.next := item ELSE root := item;
hilf^.prev := item;
END ELSE BEGIN { Sonderfall, hinter hilf anhängen }
item^.prev := hilf;
item^.next := hilf^.next;
IF hilf^.next<>Nil THEN hilf^.next^.prev := item;
hilf^.next := item;
END;
END;
END;
PROCEDURE add_to_list{(item: p_onepage)};
{ Hängt eine Seite ans Ende der Liste an. }
VAR hilf: p_onepage;
BEGIN
IF root=Nil THEN BEGIN
root := item
item^.next := Nil;
item^.prev := Nil;
END ELSE BEGIN
hilf := root;
WHILE hilf^.next<>Nil DO
hilf := hilf^.next;
{ Hinter hilf anhängen: }
hilf^.next := item;
item^.prev := hilf;
item^.next := Nil;
END;
END;
FUNCTION next_magazine{(item: p_onepage): p_onepage};
{ Erste Seite finden, die hinter <item> in der Liste steht und eine andere }
{ Magazinnummer trägt. Absichtlich so vorsichtig formuliert, damit das auch }
{ auf unsortierten Listen sinnvolle Resultate liefert. }
VAR mag: integer;
BEGIN
IF item<>Nil THEN BEGIN
mag := item^.pg DIV 100;
{ zum nächsten Magazin vorrücken }
WHILE (item^.next<>Nil) AND (item^.pg DIV 100 = mag) DO
item := item^.next;
END;
next_magazine := item;
END;
FUNCTION prev_magazine{(item: p_onepage): p_onepage};
{ Etwas komplizierter als next_magazine(), da nicht die erste Seite vor }
{ <item> mit einer anderen Magazinnummer gesucht ist, sondern von allen }
{ Seiten, die diese andere Magazinnummer tragen, die am weitesten vorne in }
{ der Liste stehende. }
VAR mag: integer;
BEGIN
IF item<>Nil THEN BEGIN
mag := item^.pg DIV 100;
{ zum vorigen Magazin }
WHILE (item^.prev<>Nil) AND (item^.pg DIV 100 = mag) DO
item := item^.prev;
mag := item^.pg DIV 100;
{ Anfang des gefundenen Magazins suchen }
WHILE (item^.prev<>Nil) AND (item^.pg DIV 100 = mag) DO
item := item^.prev;
{ Hoppla, eins zu weit ... }
IF (item^.next<>Nil) AND (item^.pg DIV 100 <> mag) THEN
item := item^.next;
END;
prev_magazine := item;
END;
BEGIN { Intialisierungsteil }
root := Nil;
END.